/*	
	BOOT0 BOOT1
	  0            0   - Main Flash memory is selected as boot space
	  1            0   - System memory is selected as boot space
*/

#include "app_porting.h"

PRODUCT_INFO_T g_product_info;

static OS_EVENT *sg_sem_product=NULL;
void sem_product_init(void)
{
	sg_sem_product=OSSemCreate(1);
	if(NULL==sg_sem_product){
		//
	}	
}

void sem_product_post(void)
{
	if(NULL!=sg_sem_product){
		OSSemPost(sg_sem_product);	
	}else{
		//
	}
}

void sem_product_pend(void)
{
	INT8U err;
	if(NULL!=sg_sem_product){
		OSSemPend(sg_sem_product,0,&err);
	}else{
		//
	}
}


static uint8_t product_info_acc8(PRODUCT_INFO_T* p_product_info)
{
	uint8_t acc8;
	uint8_t *p;
	int32_t i;
	
	if(NULL==p_product_info){
		return 0;
	}	

	p=(uint8_t *)&p_product_info->content;
	acc8=0;
	for(i=0;i<sizeof(PRODUCT_CONTENT_T);i++){
		acc8+=p[i];
	}
	return acc8;
}

static int32_t product_info_valid(PRODUCT_INFO_T* p_product_info)
{
	if(NULL==p_product_info){
		return LS_FAIL;
	}
	
	if(PRODUCT_INFO_MAGIC!=p_product_info->content.magic){
		return LS_FAIL;
	}
	
	if(product_info_acc8(p_product_info)!=p_product_info->acc8){
		return LS_FAIL;
	}
	return LS_SUCCESS;
}

int32_t product_info_read(PRODUCT_INFO_T* p_product_info)
{
	PRODUCT_INFO_T info,infoback;
	int32_t info_valid,infoback_valid;
	
	if(NULL==p_product_info){
		return LS_FAIL;
	}
	
	if(LS_SUCCESS!=stm32_flash_read(FLASH_INFO_PRODUCT,(uint8_t*)&info,sizeof(PRODUCT_INFO_T))){
		return LS_FAIL;
	}
	
	if(LS_SUCCESS!=stm32_flash_read(FLASH_INFO_PRODUCT_BACK,(uint8_t*)&infoback,sizeof(PRODUCT_INFO_T))){
		return LS_FAIL;
	}

	info_valid=product_info_valid(&info);
	infoback_valid=product_info_valid(&infoback);

	if(LS_SUCCESS==info_valid){
		if(LS_SUCCESS!=infoback_valid){
			if(LS_SUCCESS!=stm32_flash_erase(FLASH_INFO_PRODUCT_BACK,1)){
				return LS_FAIL;
			}	
			if(LS_SUCCESS!=stm32_flash_write(FLASH_INFO_PRODUCT_BACK,(uint8_t*)&info,sizeof(PRODUCT_INFO_T))){
				return LS_FAIL;
			}			
		}
		memcpy(p_product_info,&info,sizeof(PRODUCT_INFO_T));
		return LS_SUCCESS;		
	}else{
		if(LS_SUCCESS==infoback_valid){
			if(LS_SUCCESS!=stm32_flash_erase(FLASH_INFO_PRODUCT,1)){
				return LS_FAIL;
			}	
			if(LS_SUCCESS!=stm32_flash_write(FLASH_INFO_PRODUCT,(uint8_t*)&infoback,sizeof(PRODUCT_INFO_T))){
				return LS_FAIL;
			}			
			memcpy(p_product_info,&infoback,sizeof(PRODUCT_INFO_T));
			return LS_SUCCESS;	
		}else{
			return LS_FAIL;
		}
	}
}

int32_t product_info_write(PRODUCT_INFO_T* p_product_info)
{	
	if(NULL==p_product_info){
		return LS_FAIL;
	}
	
	p_product_info->content.magic=PRODUCT_INFO_MAGIC;
	p_product_info->acc8=product_info_acc8(p_product_info);
	
	if(LS_SUCCESS!=stm32_flash_erase(FLASH_INFO_PRODUCT,1)){
		return LS_FAIL;
	}	
	if(LS_SUCCESS!=stm32_flash_write(FLASH_INFO_PRODUCT,(uint8_t*)p_product_info,sizeof(PRODUCT_INFO_T))){
		return LS_FAIL;
	}
	
	if(LS_SUCCESS!=stm32_flash_erase(FLASH_INFO_PRODUCT_BACK,1)){
		return LS_FAIL;
	}	
	if(LS_SUCCESS!=stm32_flash_write(FLASH_INFO_PRODUCT_BACK,(uint8_t*)p_product_info,sizeof(PRODUCT_INFO_T))){
		return LS_FAIL;
	}
	
	return LS_SUCCESS;	
}

int32_t product_info_init(void)
{
	sem_product_init();
	sem_product_pend();
	if(LS_SUCCESS!=product_info_read(&g_product_info)){
		//
		memset(&g_product_info,0,sizeof(g_product_info));
	}	
	sem_product_post();
	return LS_SUCCESS;	
}


#ifdef WDG_ENABLE	
void iwdg_init(void)
{
	//500//0xFFF
#define RELOAD_VALUE 0xFFF

	RCC_LSICmd(ENABLE);
	while(RESET==RCC_GetFlagStatus(RCC_FLAG_LSIRDY));

	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
	while(SET==IWDG_GetFlagStatus(IWDG_FLAG_PVU));
	IWDG_SetPrescaler(IWDG_Prescaler_256);
	while(SET==IWDG_GetFlagStatus(IWDG_FLAG_RVU));
	IWDG_SetReload(RELOAD_VALUE);	
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Disable);
	IWDG_Enable();
	IWDG_ReloadCounter();
}
static void iwdg_feed(void)
{
	IWDG_ReloadCounter();
}
#endif

void idle_process(void)
{
#ifdef WDG_ENABLE
	iwdg_feed();
#endif
}

void reboot_system(void)
{
#ifdef LIB_PRINTF_SUPPORT
	printf("system will reboot.\r\n");
#endif	
	OSTimeDlyHMSM(0,0,1,0);
	NVIC_SystemReset(); 	
}

#ifdef LIB_PRINTF_SUPPORT
 //////////////////////////////////////////////////////////////////
 //加入以下代码,支持printf函数,而不需要选择use MicroLIB    
#pragma import(__use_no_semihosting)             
 //标准库需要的支持函数 				
 struct __FILE 
 { 
	 int handle; 
 }; 
 
 FILE __stdout; 	  
 //定义_sys_exit()以避免使用半主机模式	  
int _sys_exit(int x) 
 { 
	 x = x; 
	 return x;
 } 
 //重定义fputc函数 
 int fputc(int ch, FILE *f)
 {
 	while(!uart_transmit_ready(CONSOLE_DEVICE)){
		OSTimeDly(1);
 	}
	uart_putc(CONSOLE_DEVICE,ch);
	return ch;
 }
#endif

